﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Object to Object Mapping</title>
<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
</head>

<body>

<div class="document-contents">

<h3>Introduction</h3>
<p>It's a common to map a similar object to another object. It's also tedious 
and repeating since generally both objects (classes) may have similar/same 
properties mapped to each other. Think on a typical
<a href="Application-Services.html">application service</a> method below:</p>
	<pre lang="cs">public class UserAppService : ApplicationService
{
    private readonly IRepository&lt;User&gt; _userRepository;

    public UserAppService(IRepository&lt;User&gt; userRepository)
    {
        _userRepository = userRepository;
    }

    public void CreateUser(CreateUserInput input)
    {
<strong>        var user = new User
        {
            Name = input.Name,
            Surname = input.Surname,
            EmailAddress = input.EmailAddress,
            Password = input.Password
        };</strong>

        _userRepository.Insert(user);
    }
}</pre>
	<p>CreateUserInput is a simple <a href="Data-Transfer-Objects.html">DTO</a> 
	and User is a simple <a href="Entities.html">entity</a> here. We manually 
	created a User entity from given input. User entity will have much more 
	properties in a real world application and manually creating it will become 
	tedious and error-prone. Also, we should change the mapping code when we 
	want to add new properties to User and CreateUserInput.</p>
	<p>We can use a library to make this mapping automatically. 	<a href="http://automapper.org/" target="_blank">AutoMapper</a> is one of 
	the best libraries for object to object mapping. ASP.NET Boilerplate defines
	<strong>IObjectMapper</strong> interface to abstract it and implements this 
	interface using AutoMapper in
	<a href="https://www.nuget.org/packages/Abp.AutoMapper" target="_blank">
	Abp.AutoMapper</a> package.</p>
	<h3>IObjectMapper Interface</h3>
	<p>IObjectMapper is a simple abstraction that has Map methods to map an 
	object to another. We can write the sample code above as like below:</p>
<pre lang="cs">public class UserAppService : ApplicationService
{
    private readonly IRepository&lt;User&gt; _userRepository;
    <strong>private readonly IObjectMapper _objectMapper;</strong>

    public UserAppService(IRepository&lt;User&gt; userRepository, <strong>IObjectMapper objectMapper</strong>)
    {
        _userRepository = userRepository;
        _objectMapper = objectMapper;
    }

    public void CreateUser(CreateUserInput input)
    {
        <strong>var user = _objectMapper.Map&lt;User&gt;(input);</strong>
        _userRepository.Insert(user);
    }
}</pre>
	<p>Map is a simple method gets the source object and creates a new 
	destination object with the type declared as the generic parameter (User in this 
	sample). Map method has an overload to map an object to an <strong>
	existing</strong> object. Assume that we already have a User entity and want 
	to update it's properties by an object:</p>
	<pre lang="cs">public void UpdateUser(UpdateUserInput input)
{
    var user = _userRepository.Get(input.Id);
    <strong>_objectMapper.Map(input, user);</strong>
}</pre>
	<h3>AutoMapper Integration</h3>
	<p><strong>
	<a href="https://www.nuget.org/packages/Abp.AutoMapper" target="_blank">
	Abp.AutoMapper</a></strong> nuget package (<a href="Module-System.html">module</a>) 
	implements IObjectMapper and provides additional features.</p>
	<h4>Installation</h4>
	<p>First, install <strong>Abp.AutoMapper</strong> nuget to your project:</p>
	<pre>Install-Package Abp.AutoMapper</pre>
	<p>Then add a dependency for <strong>AbpAutoMapperModule</strong> to your module definition 
	class:</p>
	<pre lang="cs"><strong>[DependsOn(typeof(AbpAutoMapperModule))]</strong>
public class MyModule : AbpModule
{
    ...
}</pre>
	<p>Then you can safely <a href="Dependency-Injection.html">inject</a> and 
	use IObjectMapper in your code. You can also use
	<a href="http://automapper.org/" target="_blank">AutoMapper</a>'s own API 
	when you need.</p>
	<h4>Creating Mappings</h4>
	<p>AutoMapper requires to define mappings between classes (by default) 
	before using the mapping. You can see it's own
	<a href="http://automapper.org/" target="_blank">documentation</a> for 
	details on mapping. ASP.NET Boilerplate makes it a bit easier and modular.</p>
	<h5>Auto Mapping Attributes</h5>
	<p>Most of time you only want to directly (and conventionally) map classes. 
	In that case, you can use <strong>AutoMap</strong>, <strong>AutoMapFrom</strong> 
	and <strong>AutoMapTo</strong> attributes. For instance, as we want to map
	<strong>CreateUserInput</strong> class to <strong>User</strong> class in the 
	sample above, we can use <strong>AutoMapTo</strong> attribute as shown below:</p>
	<pre lang="cs"><strong>[AutoMapTo(typeof(User))]</strong>
public class CreateUserInput
{
    public string Name { get; set; }

    public string Surname { get; set; }

    public string EmailAddress { get; set; }

    public string Password { get; set; }
}</pre>
	<p>AutoMap attribute maps two classes in both direction. But in this sample, 
	we only need to map from CreateUserInput to User, so we used AutoMapTo.</p>
	<h5>Custom Mapping</h5>
	<p>Simple mapping may not be suitable in some cases. For instance, property 
	names of two classes may be a little different or you may want to ignore 
	some properties during the mappping. In such cases you should directly use 
	AutoMapper's API to define the mapping. Abp.AutoMapper package defines API 
	to make this custom mapping stuff more modular.</p>
	<p>Assume that we want to ignore Password on mapping and User has Email 
	property for email address. We can define mapping as shown below:</p>
	<pre lang="cs">[DependsOn(typeof(AbpAutoMapperModule))]
public class MyModule : AbpModule
{
    public override void PreInitialize()
    {
        Configuration.Modules.AbpAutoMapper().Configurators.Add(config =&gt;
        {
<strong>            config.CreateMap&lt;CreateUserInput, User&gt;()
                  .ForMember(u =&gt; u.Password, options =&gt; options.Ignore())
                  .ForMember(u =&gt; u.Email, options =&gt; options.MapFrom(input =&gt; input.EmailAddress));
</strong>        });
    }
}</pre>
	<p>AutoMapper has much more options and abilities for object to object 
	mapping. See it's <a href="http://automapper.org/" target="_blank">
	documentation</a> for more.</p>
	<h4>MapTo Extension Methods</h4>
	<p>It's suggested to inject and use IObjectMapper interface as defined 
	before. This makes our project independent from AutoMapper as much as 
	possible. It also makes unit testing easier since we can replace (mock) the 
	mapping in unit tests.</p>
	<p>Abp.AutoMapper module also defines MapTo extension methods which can be 
	used on any object to map it to another object without injecting 
	IObjectMapper. Example usage:</p>
	<pre lang="cs">public class UserAppService : ApplicationService
{
    private readonly IRepository&lt;User&gt; _userRepository;

    public UserAppService(IRepository&lt;User&gt; userRepository)
    {
        _userRepository = userRepository;
    }

    public void CreateUser(CreateUserInput input)
    {
        <strong>var user = input.MapTo&lt;User&gt;();</strong>
        _userRepository.Insert(user);
    }

    public void UpdateUser(UpdateUserInput input)
    {
        var user = _userRepository.Get(input.Id);
        <strong>input.MapTo(user);</strong>
    }
}</pre>
	<p>MapTo extension methods are defined in Abp.AutoMapper namespace, so you 
	first import this namespaces into your code file.</p>
	<p>Since MapTo extension methods are statics, they use AutoMapper's static 
	instance (Mapper.Instance). This is simple and fine for the application code, 
	but can have problems in unit tests since static configuration and mapper is 
	shared among different tests and they may effect each other.</p>
	<h4>Unit Tests</h4>
	<p>We want to isolate tests from each others. To do that, we should design 
	our project with the following rules:</p>
	<p>1. Always use IObjectMapper, not use MapTo extension methods.</p>
	<p>2. Configure Abp.AutoMapper module to use local Mapper instance 
	(registered as singleton to dependency injection) rather 
	than the static one (Abp.AutoMapper uses the static Mapper.Instance by 
	default to allow to use MapTo extension methods defined above):</p>
	<pre lang="cs">Configuration.Modules.AbpAutoMapper().UseStaticMapper = false;</pre>
	<h4>Pre Defined Mappings</h4>
	<h5>LocalizableString -&gt; string</h5>
	<p>Abp.AutoMapper module defines a mapping to convert LocalizableString (or 
	ILocalizableString) objects to string objects. It makes the conversion using
	<a href="Localization.html">ILocalizationManager</a>, so localizable 
	properties are automatically localized during the mapping process of any 
	class.</p>
	<h4>Injecting IMapper</h4>
	<p>You may need to directly use AutoMapper's IMapper object instead of 
	IObjectMapper abstraction. In that case, just inject IMapper in your classes 
	and use it. Abp.AutoMapper package registers IMapper to
	<a href="Dependency-Injection.html">dependency injection</a> as singleton.</p>

</div>

</body>

</html>
